<?php

// +----------------------------------------------------------------------
// | THINKPHP                                                      
// +----------------------------------------------------------------------
// | Copyright (c) 2010 http://scotoma.cnblogs.com All rights reserved.      
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: solosky ，some change by scotoma  20100305                                  
// +----------------------------------------------------------------------
// $Id$
/**
 +------------------------------------------------------------------------------
 * 分类管理
 +------------------------------------------------------------------------------
 * @Category   Com
 * @package  Com
 * @subpackage  API
 * @author    scotoma
 * @version   $Id$
 +------------------------------------------------------------------------------
 */

/*
分类表的结构，可以根据需要添加其他字段
建议取名为:  Category (我不喜欢sort)
+--------+---------------------+------+-----+---------+----------------+----------+-------------------+
| Field  | Type                | Null | Key | Default | Extra          | Required | Intro             |
+--------+---------------------+------+-----+---------+----------------+----------+-------------------+
| id  | tinyint(4) unsigned | NO   | PRI | NULL    | auto_increment | YES      | 分类的主键        |
| title  | varchar(255)        | NO   |     |         |                | YES      | 分类的标题        |
| parentid    | tinyint(4)          | NO   |     |         |                | YES      | 上级分类ID        |
| intro  | varchar(500)        | YES  |     | NULL    |                | NO       | 分类的详细介绍    |
| status | tinyint(1)          | NO   |     | 1       |                | NO       | 分类的状态        |
+--------+---------------------+------+-----+---------+----------------+----------+-------------------+
*/

class Category
{	
	//分类的数据表模型
	private $model;
	//原始的分类
	private $rawList=array();
    //格式化后的分类
    private $formatList=array();
	//错误信息  
	private $error="";
	//格式化的字符
	private $icon = array('│','├','└');

	 /**
     +----------------------------------------------------------
     * 架构函数
     * 默认的系统树的表名为category
     +----------------------------------------------------------
     * @access public 
     +----------------------------------------------------------
     * @param mixed $model 分类表的数据模型实例或者模型名
     +----------------------------------------------------------
     */
	 public function __construct($model='category')
	{
		//判断参数类型
		if(is_string($model)){
			if(!$this->model=D($model))
				throw_exception($model."is not find！");
		}
		elseif(is_object($model))
			$this->model=&$model;
		else{
			throw_exception("para error！");
		}
	}


	 /**
     +----------------------------------------------------------
     * 返回对应的模型
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param void
     +----------------------------------------------------------
     * @return Model Object 当前分类表的数据模型
     +----------------------------------------------------------
     */
	public function getModel()
	{
		return $this->model;
	}

	  /**
     +----------------------------------------------------------
     * 返回所有的子分类
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param string $CatID 分类ID
     +----------------------------------------------------------
     * @return string 子分类
     +----------------------------------------------------------
     */
	public function getChild($pid)
	{
		$childs=array();
		foreach($this->rawList as $Category)
		{
			if($Category['parentid']==$pid)
				$childs[]=$Category;
		}
		return $childs;
	}
	  /**
     +----------------------------------------------------------
     * 递归格式化分类前的字符
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param string $CatID 分类ID
     * @param string $space  填充字符
     +----------------------------------------------------------
     * @return string void
     +----------------------------------------------------------
     */
	private function _searchList($CatID=0,$space="")
	{
		//下级分类的数组
		$childs=$this->getChild($CatID);
		//如果没下级分类，结束递归
		if(!($n=count($childs)))
			return;
		$cnt=1;
		//循环所有的下级分类
		for($i=0;$i<$n;$i++){
			$pre="";
			$pad="";
			if($n==$cnt){
				$pre=$this->icon[2];
			}
			else{
				$pre=$this->icon[1];
				$pad=$space?$this->icon[0]:"";
			}
			$childs[$i]['fulltitle']=($space?$space.$pre:"").$childs[$i]["title"];
		$this->formatList[]=$childs[$i];
		//递归下级分类
		//change by scotoma
		$this->_searchList($childs[$i]["id"],$space.$pad."&nbsp;&nbsp;");
		$cnt++;
		}
	}
	  /**
     +----------------------------------------------------------
     * 格式化分类列表
     +----------------------------------------------------------
     * @access public 
     +----------------------------------------------------------
     * @param string $CatID 分类ID
     +----------------------------------------------------------
     * @return string void
     +----------------------------------------------------------
     */
	public function getList($CatID=0)
	{
		$this->_findAllCat();
		$this->_searchList($CatID);
		return $this->formatList;
	}


     /**
     +----------------------------------------------------------
     * 查询路径
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param integer $CatID  分类的ID
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
	 private function _searchPath($CatID)
	{
		
		//检查参数
		if(!$this->_checkCatID($CatID)){
			return false;
		}
		//初始化对象，查找上级Id；
		$rs=$this->model->find($CatID);

		//保存结果
		$this->formatList[]=$rs;

		$this->_searchPath($rs['parentid']);
	}

	 /**
     +----------------------------------------------------------
     * 根据给定的分类id，查询分类路径
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param integer $CatID  分类的ID
     +----------------------------------------------------------
     * @return array 分类的路径
     +----------------------------------------------------------
     */

	public function getPath($CatID)
	{
		//检查参数
		if(!$this->_checkCatID($CatID))
			return false;
		//检查模型
		if(!$this->_checkModel())
			return false;
		
		//查询分类路径
		$this->_searchPath($CatID);

		return array_reverse($this->formatList);
	}



	

     /**
     +----------------------------------------------------------
     * 返回给定分类ID的所有子分类 TODO:BUG 同级的也在里面
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param integer $CatID  分类的ID
     +----------------------------------------------------------
     * @return array 子分类的数组
     +----------------------------------------------------------
     */
	public function getSubList($CatID)
	{		
		//检查参数
		if(!$this->_checkCatID($CatID))
			return false;
		//查询下级分类
		$this->_searchList($CatID);
		//返回结果
		return $this->formatList;
	}

     /**
     +----------------------------------------------------------
     * 返回给定分类ID的所有子分类的ID
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param integer $CatID  分类的ID
     +----------------------------------------------------------
     * @return array 子分类ID的数组
     +----------------------------------------------------------
     */
	public function getSubListID($CatID)
	{	
		//检查参数
		if(!$this->_checkCatID($CatID))
			return false;

		//初始化对象，查找上级Id；
		$this->_findAllCat();

		//查询下级分类
		$this->_searchList($CatID);
		//处理结果，返回一个数组，下标和值均为分类的ID
		//TODO:by xinqiyang CatID,CatID 换成 id,id
		$CatIDs=$this->getCols('id,id');
	
		return array_keys($CatIDs);

	}

     /**
     +----------------------------------------------------------
     * 返回结果集的两行
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $cols 字段的名字
     +----------------------------------------------------------
     * @return array 结果集的两行
     +----------------------------------------------------------
     */
	
	public function getCols($cols)
	{
		if(!$this->_checkList())
			return false;
		//TODO:bug 这里没有2个参数的
		return $this->model->getCols($this->formatList,$cols);
	}
	
	
     /**
     +----------------------------------------------------------
     * 根据一个字段查询分类
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param string $field 字段的名字
     * @param string $value 字段的值
     * @param boolean $all  是否返回全部
     +----------------------------------------------------------
     * @return array 查询结果
     +----------------------------------------------------------
     */
	public function getBy($field,$value,$all=false)
	{
		if($all)
			return $this->model->getByAll($field,$value);
		else
			return $this->model->getBy($field,$value);
	}

     /**
     +----------------------------------------------------------
     * 返回错误
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @param void
     +----------------------------------------------------------
     * @return string 错误信息
     +----------------------------------------------------------
     */
	public function getError()
	{
		return $this->error;
	}


     /**
     +----------------------------------------------------------
     * 检查模型是否为空
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param void
     +----------------------------------------------------------
     * @return boolean
     +----------------------------------------------------------
     */
	private function _checkModel()
	{
		if(!is_object($this->model)){
			$this->error="DataModel is null";
			return false;
		}
		else
			return true;
	}


     /**
     +----------------------------------------------------------
     * 检查结果是否为空
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param void
     +----------------------------------------------------------
     * @return boolean
     +----------------------------------------------------------
     */
	private function _checkList()
	{
		if(empty($this->formatList)){
			$this->error="the result is null!";
			return false;
		}
		else
			return true;
	}

     /**
     +----------------------------------------------------------
     * 检查分类参数是否为空
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param void
     +----------------------------------------------------------
     * @return boolean
     +----------------------------------------------------------
     */
	private function _checkCatID($CatID)
	{
		if(intval($CatID))
			return true;
		else{
			$this->error="parameter catID is null！";
			return false;
		}
	}
	
	/**
     +----------------------------------------------------------
     * 查询所有的分类
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @param void
     +----------------------------------------------------------
     * @return boolean
     +----------------------------------------------------------
     */
    private function _findAllCat()
    {
        $this->rawList=$this->model->findAll();
    }
}

?>